using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.Logic;
using NetProtocol.POD;
using System;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class LocalLogicManager : Singleton<LocalLogicManager>
    {
        private LocalLogicManager() { }

        private bool inited = false;
        private uint m_LogicUpdateTimerId;
        public LocalLogicClientSession localLogicClientSession { get; private set; }
        public LocalLogicServerSession localLogicServerSession { get; private set; }

        public LogicPlayer logicPlayer { get; private set; }

        public void Init(LogicPlayerPOD playerPod)
        {
            if (inited)
            {
                InitPlayer(playerPod);
                return;
            }

            inited = true;
            InitLogicHelper();
            LocalLogicServerNetHandler.Instance.Init();
            localLogicClientSession = new LocalLogicClientSession();
            localLogicServerSession = new LocalLogicServerSession();
            InitPlayer(playerPod); // 依赖session

            SLevelLogicModule.Instance.LogicStart();
            SBattleLogicModule.Instance.LogicStart();
            m_LogicUpdateTimerId = TimerManager.Instance.StartTimer(LogicUpdate, 1f / LogicConst.FrameRate, -1, TimerType.FixTime);
        }

        private void InitPlayer(LogicPlayerPOD playerPod)
        {
            logicPlayer = new LogicPlayer(playerPod);
            logicPlayer.session = localLogicServerSession;
            logicPlayer.isOnline = true;
        }

        private void InitLogicHelper()
        {
            LogicHelper.AllocGUID = LocalGUIDAllocator.Instance.AllocAndWaitId;
            LogicHelper.LogicServerId = "0";
            LogicHelper.TimeProvider = () => GameServerModule.Instance.CurrSession == null ? DateTimeOffset.Now.ToUnixTimeMilliseconds() : GameServerModule.Instance.ServerTimeMillis;
            LogicHelper.GetTbCfgStory = (tbName) => GetTbCfgStoryFuncOnMainThread(tbName).AsTask().Result;

            async static UniTask<StoryConfig> GetTbCfgStoryFuncOnMainThread(string tbName)
            {
                await UniTask.SwitchToMainThread();
                ResLoader resloader = ResLoader.Create();
                var path = $"{PathConstant.StoryCfgPath}{eLanguageType.ZH_CN.ToString()}/{tbName.ToLower()}.bytes";
                var textAsset = resloader.LoadABAsset<TextAsset>(path);
                var tbCfgStory = StoryFactory.Create(textAsset.bytes);
                resloader.Put2Pool();
                return tbCfgStory;
            }
        }

        // Editor模式下线程退出以后该对象就销毁了。
        public void Shutdown()
        {
            if (!inited)
            {
                return;
            }
            inited = false;
            if (m_LogicUpdateTimerId != 0)
            {
                TimerManager.Instance.StopTimer(m_LogicUpdateTimerId);
                m_LogicUpdateTimerId = 0;
            }
            SLevelLogicModule.Instance.LogicStop();
            SBattleLogicModule.Instance.LogicStop();
            localLogicClientSession = null;
            localLogicServerSession = null;
            inited = false;
            LocalLogicServerNetHandler.Instance.Shutdown();
        }

        private void LogicUpdate()
        {
            try
            {
                //帧刷
                SLevelLogicModule.Instance.LogicOnUpdate();
                SBattleLogicModule.Instance.LogicOnUpdate();
            }
            catch (Exception e)
            {
                LogicLog.LogException(e);
            }
        }

    }
}
